<template>
  <div v-show="!showAlgo">
    <!-- 上传视频 -->
    <n-upload
      ref="uploadRef"
      :action="uploadUrl"
      :max="1"
      :with-credentials="true"
      :custom-request="uploadRequest"
      class="uploads"
      @before-upload="beforeUpload"
    >
      <n-upload-dragger style="width: 500px">
        <div style="margin-bottom: 12px">
          <n-icon size="48" :depth="3">
            <upload-icon />
          </n-icon>
        </div>
        <n-text style="font-size: 16px" :depth="3"
          >Drop File Here or Clik to Upload</n-text
        >
      </n-upload-dragger>
    </n-upload>
    <n-h2>
      <n-text>Examples</n-text>
    </n-h2>
    <n-data-table
      :columns="createColumns({ choose })"
      :data="exampleData.data"
      :pagination="false"
      :bordered="false"
    />
  </div>
  <div v-show="showAlgo">
    <n-space justify="space-around">
      <div class="img-container">
        <video width="450" :src="sourceVideo" controls="controls" />
        <n-h3>
          <n-text :depth="3" :strong="true">Input</n-text>
          <n-button
            quaternary
            circle
            type="success"
            tag="a"
            :href="
              sourceVideo + '?response-content-type=application/octet-stream'
            "
            download
          >
            <template #icon>
              <n-icon>
                <download-icon />
              </n-icon>
            </template>
          </n-button>
        </n-h3>
      </div>
      <div class="img-container" v-show="targetVideo !== ''">
        <video width="450" :src="targetVideo" controls="controls" />
        <n-h3>
          <n-text :depth="3" :strong="true">Output</n-text>
          <n-button
            quaternary
            circle
            type="success"
            tag="a"
            :href="
              targetVideo + '?response-content-type=application/octet-stream'
            "
            download
          >
            <template #icon>
              <n-icon>
                <download-icon />
              </n-icon>
            </template>
          </n-button>
        </n-h3>
      </div>
    </n-space>
    <n-space justify="end">
      <n-button type="tertiary" @click="handleClear" :disabled="isExecuting"
        >Clear</n-button
      >
      <n-button type="primary" @click="handleExecute" :disabled="isExecuting"
        >Execute</n-button
      >
    </n-space>
  </div>
</template>

<script setup>
import {
  CloudUploadOutline as UploadIcon,
  DownloadOutline as DownloadIcon
} from '@vicons/ionicons5'
import { useMessage, useLoadingBar, NImage, NButton } from 'naive-ui'
import axios from 'axios'

const uploadUrl = 'http://47.93.249.243:8000/file/upload/'

const executeUrl = 'http://47.93.249.243:8000/file/execute/'

const message = useMessage()

onMounted(() => {
  handleClear()
})

// 展示算法
const showAlgo = ref(false)

const uploadRef = ref()

// 原视频
const sourceVideo = ref('')
// 目标视频
const targetVideo = ref('')

// 文件类型检测
const beforeUpload = (data) => {
  if (data.file.file?.type !== 'video/mp4') {
    message.error('Only MP4 video files can be uploaded')
    return false
  }
  return true
}

// 上传请求
const uploadRequest = ({
  file,
  data,
  headers,
  withCredentials,
  action,
  onFinish,
  onError,
  onProgress
}) => {
  const formData = new FormData()
  formData.append('file', file.file)
  axios({
    url: action,
    method: 'POST',
    headers: { 'Content-Type': 'multipart/form-data' },
    data: formData,
    timeout: 0,
    onUploadProgress: ({ loaded, total }) => {
      onProgress({ percent: Math.ceil((loaded / total) * 100) })
    }
  })
    .then((res) => {
      if (res.data.success) {
        message.success('Successfully uploaded')
        showAlgo.value = true
        sourceVideo.value = res.data.url
      }
    })
    .catch(() => {
      message.error('Video upload failed, please try again')
    })
}

const loadingBar = useLoadingBar()

// 清空视频回调
const handleClear = () => {
  sourceVideo.value = ''
  targetVideo.value = ''
  uploadRef.value.clear()
  showAlgo.value = false
  isExample.value = false
  exampleInterval.value && clearInterval(exampleInterval.value)
}

const isExecuting = ref(false)

// 是否是示例视频
const isExample = ref(false)
// 实例视频定时器
const exampleInterval = ref()

// 执行回调
const handleExecute = () => {
  loadingBar.start()
  isExecuting.value = true
  if (isExample.value) {
    exampleInterval.value = setTimeout(() => {
      message.success('Successful execution')
      targetVideo.value = '/assets/example/egvideo2.mp4'
      loadingBar.finish()
      isExecuting.value = false
    }, 5000)
  } else {
    axios({
      url: executeUrl,
      method: 'POST',
      data: {
        url: sourceVideo.value
      },
      timeout: 0
    })
      .then((res) => {
        if (res.data.success) {
          message.success('Successful execution')
          targetVideo.value = res.data.url
          loadingBar.finish()
          isExecuting.value = false
        }
      })
      .catch(() => {
        message.error('Execution failed, please try again')
        loadingBar.error()
        isExecuting.value = false
      })
  }
}

const choose = () => {
  sourceVideo.value = '/assets/example/egvideo1.mp4'
  targetVideo.value = ''
  showAlgo.value = true
  isExample.value = true
}

// 创建表头
const createColumns = ({ choose }) => {
  return [
    {
      title: 'Video',
      key: 'url',
      render(row) {
        return h(NImage, {
          src: row.url,
          width: '300'
        })
      }
    },
    {
      title: 'Action',
      key: 'actions',
      align: 'center',
      width: '300',
      render(row) {
        return h(
          NButton,
          {
            strong: true,
            size: 'small',
            type: 'primary',
            onClick: () => choose()
          },
          { default: () => 'Choose' }
        )
      }
    }
  ]
}

// 示例数据
const exampleData = {
  data: [{ url: '/assets/example/egimg2.jpg' }]
}
</script>

<style scoped>
.uploads {
  text-align: center;
}

.img-container {
  display: flex;
  flex-direction: column;
  text-align: center;
}
</style>
